#include "vxWorks.h"
#include "stdio.h"
#include "stdlib.h"
#include "sysLib.h"
#include "ioLib.h"
#include "taskLib.h"
#include "math.h"
#include "string.h"
#include "logLib.h"
#include "intLib.h"
#include "iv.h"
#include "drv/pci/pciConfigLib.h"
#include "drv/pci/pciIntLib.h"
#include "math.h"
#include "pci.h"
#include "vx9116.h"

#if (CPU==PPC85XX)
#include "arch/ppc/ivPpc.h"
#else
#include "arch/i86/ivI86.h"
#include "../config/pcPentium/configInum.h"
#include "../config/pcPentium/config.h"
#endif

#if 1
#define FILENAME "host:9116.rbf"
#else
#define FILENAME "/ahci00:1/9116.rbf"
#endif

#define TMP_BUF_SIZE 80

#if(CPU==PPC85XX)

#define Local_sysInWord(addr) sysPciInWord(addr)
#define Local_sysInLong(addr) sysPciInLong(addr)
#define Local_sysOutWord(addr, pdata) sysPciOutWord(addr, pdata)
#define Local_sysOutLong(addr, pdata) sysPciOutLong(addr, pdata)

#else

#define Local_sysInWord(addr) sysInWord(addr)
#define Local_sysInLong(addr) sysInLong(addr)
#define Local_sysOutWord(addr, pdata) sysOutWord(addr, (unsigned short)(pdata))
#define Local_sysOutLong(addr, pdata) sysOutLong(addr, (unsigned long)(pdata))

#endif

LOCAL float cPCI9116_pdData[CPCI9116_BOARD_MAX][2][BUFFSIZE];
LOCAL float cPCI9116_pdData_Chan[CPCI9116_BOARD_MAX][CPCI9116_CHANNEL_MAX][BUFFSIZE];
LOCAL unsigned short cPCI9116_pulData[CPCI9116_BOARD_MAX][2][BUFFSIZE];
LOCAL char cPCI9116_szFlag[CPCI9116_BOARD_MAX] = { 0 };

/*save board's address*/
LOCAL CPCI_INFO_ST cPCI9116_stInfo[CPCI9116_BOARD_MAX] =
{
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
};

LOCAL unsigned char cPCI9116_uchOutData[CPCI9116_BOARD_MAX] ={ 0 };

/*there are 8 dio channels*/
LOCAL unsigned char cPCI9116_uchMask[8] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
LOCAL CPCI9116_ADRANGE_ST cPCI9116_stAdRange[CPCI9116_BOARD_MAX][CPCI9116_CHANNEL_MAX];

LOCAL unsigned char cPCI9116_uchCGQCount[CPCI9116_BOARD_MAX] = { 0 };
LOCAL unsigned long cPCI9116_ulScanCount[CPCI9116_BOARD_MAX] = { 0 };

int cPCI9116_Init(unsigned char uchBoardNo)
{
    int BusNo = 0;
    int DeviceNo = 0;
    int FuncNo = 0;
    UINT32 ulBaseAddr = 0;
    UINT8 uchIrqNo = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_Init:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 1)
    {
        return OK;
    }

    /*find the nth device with the given device & vendor ID*/
    if (pciFindDevice(CPCI9116_VENDERID, CPCi9116_DEVID, uchBoardNo, &BusNo, &DeviceNo, &FuncNo) != OK)
    {
        printf("cPCI9116_Init:can not find the specified device \n");
        return ERROR;
    }

    /* read card's controller address */
    if (pciConfigInLong(BusNo, DeviceNo, FuncNo, PCI_CFG_BASE_ADDRESS_0, &ulBaseAddr) == OK)
    {
        ulBaseAddr &= 0xfffffffc;

#if(CPU==PPC85XX)
        sysBusToLocalAdrs(PCI_SPACE_IO_SEC, (char *)ulBaseAddr, (char **)&ulBaseAddr);
#endif

        cPCI9116_stInfo[uchBoardNo].ulCtrlAddr = ulBaseAddr;

    }
    else
    {
        printf("cPCI9116_Init:get controller address failed \n");
        return ERROR;
    }

    /* read card's base address */
    if (pciConfigInLong(BusNo, DeviceNo, FuncNo, PCI_CFG_BASE_ADDRESS_1, &ulBaseAddr) == OK)
    {
        ulBaseAddr &= 0xfffffffc;

#if(CPU==PPC85XX)
        sysBusToLocalAdrs(PCI_SPACE_IO_SEC, (char *)ulBaseAddr, (char **)&ulBaseAddr);
#endif

        cPCI9116_stInfo[uchBoardNo].ulBaseAddr = ulBaseAddr;

    }
    else
    {
        printf("cPCI9116_Init:get base address failed \n");
        return ERROR;
    }

    /* read card's FPGA address */
    if (pciConfigInLong(BusNo, DeviceNo, FuncNo, PCI_CFG_BASE_ADDRESS_3, &ulBaseAddr) == OK)
    {
        ulBaseAddr &= 0xfffffffc;

#if(CPU==PPC85XX)
        sysBusToLocalAdrs(PCI_SPACE_IO_SEC, (char *)ulBaseAddr, (char **)&ulBaseAddr);
#endif

        cPCI9116_stInfo[uchBoardNo].ulFPGAAddr = ulBaseAddr;

    }
    else
    {
        printf("cPCI9116_Init:get FPGA address failed \n");
        return ERROR;
    }

    /* read card's interrupt level */
    if (pciConfigInByte(BusNo, DeviceNo, FuncNo, PCI_CFG_DEV_INT_LINE, &uchIrqNo) == OK)
    {
        cPCI9116_stInfo[uchBoardNo].uchIrqNo = uchIrqNo;
    }
    else
    {
        printf("cPCI9116_Init:get interrupt level failed \n");
        return ERROR;
    }

    /*download the FPGA code*/
    if (FPGA_Download(uchBoardNo) != OK)
    {
        printf("cPCI9116_Init:FPGA download error \n");
        return ERROR;
    }

    /*Init the pci controller AMCC5935*/
    Reset5935(uchBoardNo);

    bzero((char *) &cPCI9116_stAdRange[uchBoardNo], sizeof(CPCI9116_ADRANGE_ST) * CPCI9116_CHANNEL_MAX);

    cPCI9116_szFlag[uchBoardNo] = 0;

    /*here we can claim that init is successful*/
    cPCI9116_stInfo[uchBoardNo].uchInit = 1;

    printf("9116:Init success!\n");
    return OK;

}

/*read the specified uchBoardNo board's di*/
int cPCI9116_DI_Read(unsigned char uchBoardNo, unsigned char *puchData)
{
    unsigned long ulTemp = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_DI_Read:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (puchData == NULL)
    {
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_DI_Read:Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_DI_OFFSET);
    *puchData = ulTemp & 0xff;

    return OK;
}

/*test function*/
void cPCI9116_Test_DI(unsigned char uchBoardNo)
{
    unsigned char uchData = 0;

    cPCI9116_DI_Read(uchBoardNo, &uchData);

    printf("cPCI9116_Test_DI: uchData = 0x%x\n", uchData);
}

/*read the specified uchBoardNo board's specified uchChannel channel's di*/
int cPCI9116_DI_Read_Chan(unsigned char uchBoardNo, unsigned char uchChannel, unsigned char *puchData)
{
    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_DI_Read_Chan:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (uchChannel > 7)
    {
        printf("cPCI9116_DI_Read_Chan:the channel should be less than 8 \n");
        return ERROR;
    }

    if (puchData == NULL)
    {
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_DI_Read_Chan:Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    if (cPCI9116_DI_Read(uchBoardNo, puchData) == OK)
    {
        /*get the specified channel's input*/
        *puchData = ((*puchData) >> uchChannel) & 0x01;
    }
    else
    {
        return ERROR;
    }

    return OK;
}

/*test function*/
void cPCI9116_Test_DI_Chan(unsigned char uchBoardNo, unsigned char uchChannel)
{
    unsigned char uchData = 0;

    cPCI9116_DI_Read_Chan(uchBoardNo, uchChannel, &uchData);

    printf("cPCI9116_Test_DI_Chan: uchData = %d\n", uchData);
}

/*write DO to the specified uchBoardNo board*/
int cPCI9116_DO_Write(unsigned char uchBoardNo, unsigned char uchData)
{
    unsigned long ulTemp = 0;
    unsigned long ulData = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_DO_Write:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_DO_Write:Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_DO_OFFSET);

    ulTemp = ulTemp >> 8;
    ulTemp &= 0xffffff00;

    ulData = uchData;
    ulData &= 0x000000ff;

    ulData = ulTemp | ulData;

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_DO_OFFSET, ulData);

    cPCI9116_uchOutData[uchBoardNo] = uchData;

    return OK;
}

/*write DO to the specified uchBoardNo board's specified uchChannel channel*/
int cPCI9116_DO_Write_Chan(unsigned char uchBoardNo, unsigned char uchChannel, unsigned char uchData)
{
    unsigned char uchOutData = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_DO_Write_Chan: the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (uchChannel > 7)
    {
        printf("cPCI9116_DO_Write_Chan: the channel should be less than 8 \n");
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_DO_Write_Chan: Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    if ((uchData != 0) && (uchData != 1))
    {
        printf("cPCI9116_DO_Write_Chan: uchData should be 0 or 1 \n");
        return ERROR;
    }

    /*do not change the output of the unchanged channel*/
    uchOutData = (cPCI9116_uchOutData[uchBoardNo] & cPCI9116_uchMask[uchChannel]) | (uchData << uchChannel);
    cPCI9116_DO_Write(uchBoardNo, uchOutData);

    return OK;
}

/*Init the pci controller AMCC5935,according to the driver source*/
void Reset5935(unsigned char uchBoardNo)
{
    /** set MWTC a nonzero value */
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x28, 256);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x30, 256);

    /** reset mailbox flag and FIFO status */
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x3c, 0x0E002200);

    /* clear all interrupt flags */
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x38, 0x28BF0000);

}

STATUS FPGA_Download(unsigned char uchBoardNo)
{
    FILE *fp = NULL;
    char szBuff[TMP_BUF_SIZE];
    unsigned long ulReadlen = 0;
    char end_of_file = 0;
    char download_done = 0;
    char download_err = 0;
    int i = 0;
    unsigned short ushCfgData = 0;
    unsigned long ulByteCnt = 0;
    unsigned long status = 0;
    bzero(szBuff, sizeof(szBuff));

    /*here for FPGA control*/
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x3c, 0x0f000000);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x3c, 0x0);

    fp = fopen(FILENAME, "r");

    if (fp == NULL)
    {
        printf("FPGA_Download: can not open file %s \n", FILENAME);
        return ERROR;
    }

    Local_sysOutWord(cPCI9116_stInfo[uchBoardNo].ulFPGAAddr, FPGA_CONFIG);
    taskDelay(1);

    status = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulFPGAAddr);
    if ((status & FPGA_STATUS) != 0)
    {
        /*status did not goes low, something wrong*/
        printf("FPGA_Download: status did not goes low, something wrong \n");
        fclose(fp);

        return ERROR;
    }

    Local_sysOutWord(cPCI9116_stInfo[uchBoardNo].ulFPGAAddr, 0);
    taskDelay(1);

    status = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulFPGAAddr);
    if ((status & FPGA_STATUS) == 0)
    {
        /*status did not goes high, something wrong*/
        printf("FPGA_Download: status did not goes high, something wrong \n");
        fclose(fp);

        return ERROR;
    }

    while ((!end_of_file) && (!download_done))
    {
        bzero(szBuff, sizeof(szBuff));
        ulReadlen = fread(szBuff, sizeof(char), TMP_BUF_SIZE, fp);

        if (ulReadlen < 0)
        {
            printf("FPGA_Download: read file %s error \n", FILENAME);
            fclose(fp);

            return ERROR;
        }
        else if (ulReadlen < TMP_BUF_SIZE)
        {
            end_of_file = 1;
        }

        for (i = 0; i < ulReadlen; i++)
        {
            ushCfgData = ((unsigned short) (szBuff[i])) & 0x00ff;
            Local_sysOutWord(cPCI9116_stInfo[uchBoardNo].ulFPGAAddr, ushCfgData);
            ulByteCnt++;
            /*wait until data to clock into FPGA*/
            while (((status = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulFPGAAddr)) & FPGA_DATA_BUSY) != 0);

            if ((status & FPGA_INIT_DONE) && (status & FPGA_CONFIG_DONE))
            {
                download_done = 1;
                break;
            }

            if ((status & FPGA_STATUS) == 0)
            {
                download_err = 1;
                printf("FPGA_Download: download error");
                fclose(fp);

                return ERROR;
            }
        }
    }

    if (!download_err)
    {
        taskDelay(1);
        if ((Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulFPGAAddr) & FPGA_INIT_DONE) != 0)
        {
            printf("FPGA_Download: FPGA download successfully \n");
        }
    }

    fclose(fp);

    return OK;
}

/* channel gain queue set
 * uchBoardNo : the specified board
 * uchChannel : the specified channel
 * uchGain : 0  gain 1
 1  gain 2
 2  gain 4
 3  gain 8
 * szDiff : 0 single ended input signal
 1 differential input signal
 * szUnipolar : 0 bipolar
 1 unipolar */
int cPCI9116_CFIFO_Set(unsigned char uchBoardNo, unsigned char uchChannel, unsigned char uchGain, char szDiff, char szUnipolar)
{
    CPCI9116_REG_UNION stReg;

    stReg.ulTemp = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_CFIFO_Set: the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (uchChannel > 63)
    {
        printf("cPCI9116_CFIFO_Set: the channel should be less than 64 \n");
        return ERROR;
    }

    if (uchGain > 3)
    {
        printf("cPCI9116_CFIFO_Set: the gain should be less than 4 \n");
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_CFIFO_Set: Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    if (szUnipolar)
    {
        stReg.stAdConfig.InputSignalPolar = 1;
    }
    else
    {
        stReg.stAdConfig.InputSignalPolar = 0;
    }

    if (szDiff)
    {
        stReg.stAdConfig.InputSignalEnding = 1;

        if (uchChannel > 31)
        {
            return ERROR;
        }

        if (uchChannel < 16)
        {
            stReg.stAdConfig.EnableMultiplexer = 0x5;
            stReg.stAdConfig.AdChan = uchChannel;
            stReg.stAdConfig.HL_Sel = 0;
        }
        else
        {
            stReg.stAdConfig.EnableMultiplexer = 0xa;
            stReg.stAdConfig.AdChan = uchChannel - 16;
            stReg.stAdConfig.HL_Sel = 0;
        }

    }
    else
    {
        stReg.stAdConfig.InputSignalEnding = 0;

        if (uchChannel > 63)
        {
            return ERROR;
        }

        if (uchChannel < 16)
        {
            stReg.stAdConfig.EnableMultiplexer = 0x1;
            stReg.stAdConfig.AdChan = uchChannel;
            stReg.stAdConfig.HL_Sel = 0;
        }
        else if ((uchChannel >= 16) && (uchChannel < 32))
        {
            stReg.stAdConfig.EnableMultiplexer = 0x2;
            stReg.stAdConfig.AdChan = uchChannel - 16;
            stReg.stAdConfig.HL_Sel = 0;
        }
        else if ((uchChannel >= 32) && (uchChannel < 48))
        {
            stReg.stAdConfig.EnableMultiplexer = 0x4;
            stReg.stAdConfig.AdChan = uchChannel - 32;
            stReg.stAdConfig.HL_Sel = 1;
        }
        else if ((uchChannel >= 48) && (uchChannel < 64))
        {
            stReg.stAdConfig.EnableMultiplexer = 0x8;
            stReg.stAdConfig.AdChan = uchChannel - 48;
            stReg.stAdConfig.HL_Sel = 1;
        }
    }

    cPCI9116_uchCGQCount[uchBoardNo]++;
    if (cPCI9116_uchCGQCount[uchBoardNo] > 64)
    {
        /*no more than 64 channels can be configed in the channel gain queue*/
        return OK;
    }

    stReg.stAdConfig.AdGain = uchGain & 0x3;

#if 0
    if(stReg.stAdConfig.InputSignalPolar == 1)
    {
        if(stReg.stAdConfig.AdGain == 3)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65536.0 * 1.25;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
        else if(stReg.stAdConfig.AdGain == 2)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65536.0 * 2.5;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
        else if(stReg.stAdConfig.AdGain == 1)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65536.0 * 5.0;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
        else
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65536.0 * 10.0;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
    }
    else
    {
        if(stReg.stAdConfig.AdGain == 3)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 0.625;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = -0.625;
        }
        else if(stReg.stAdConfig.AdGain == 2)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 1.25;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = -1.25;
        }
        else if(stReg.stAdConfig.AdGain == 1)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 2.5;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = -2.5;
        }
        else
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 5.0;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = -5.0;
        }
    }
#endif
    if (stReg.stAdConfig.InputSignalPolar == 1)
    {
        if (stReg.stAdConfig.AdGain == 3)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65535.0 * 1.25;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.625;
        }
        else if (stReg.stAdConfig.AdGain == 2)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65535.0 * 2.5;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 1.25;
        }
        else if (stReg.stAdConfig.AdGain == 1)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65535.0 * 5.0;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 2.5;
        }
        else
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 65535.0 * 10.0;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 5.0;
        }
    }
    else
    {
        if (stReg.stAdConfig.AdGain == 3)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 0.625;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
        else if (stReg.stAdConfig.AdGain == 2)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 1.25;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
        else if (stReg.stAdConfig.AdGain == 1)
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 2.5;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
        else
        {
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dResolution = 1.0 / 32768.0 * 5.0;
            cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].dValue = 0.0;
        }
    }

    cPCI9116_stAdRange[uchBoardNo][cPCI9116_uchCGQCount[uchBoardNo] - 1].uchChanNo = uchChannel;

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_CHANNELCONFIG_OFFSET, stReg.ulTemp);

    return OK;
}

/*channel gain queue set complete*/
int cPCI9116_CFIFO_SetDone(unsigned char uchBoardNo)
{
    CPCI9116_REG_UNION stReg;

    stReg.ulTemp = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_CFIFO_SetDone:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_CFIFO_SetDone:Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    stReg.stAdCtrl.ConfigFifoSetDone = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADFIFOCONTROL_OFFSET, stReg.ulTemp);

    return OK;
}

/*clear channel gain queue*/
int cPCI9116_CFIFO_Clear(unsigned char uchBoardNo)
{
    CPCI9116_REG_UNION stReg;

    stReg.ulTemp = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_CFIFO_Clear:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_CFIFO_Clear:Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    stReg.stAdCtrl.ClearConfigFifo = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADFIFOCONTROL_OFFSET, stReg.ulTemp);

    cPCI9116_uchCGQCount[uchBoardNo] = 0;
    bzero((char *) &cPCI9116_stAdRange[uchBoardNo], sizeof(CPCI9116_ADRANGE_ST) * CPCI9116_CHANNEL_MAX);

    return OK;

}

int cPCI9116_ResetAD(unsigned char uchBoardNo)
{
    CPCI9116_REG_UNION stReg;

    stReg.ulTemp = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_ResetAD:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_ResetAD:Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    /*clear trig control regiter*/
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADTRIGGERMODE_OFFSET, 0);

    /*clear data fifo*/
    stReg.stAdCtrl.ClearDataFifo = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADFIFOCONTROL_OFFSET, stReg.ulTemp);

    /*clear config fifo*/
    stReg.ulTemp = 0;
    stReg.stAdCtrl.ClearConfigFifo = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADFIFOCONTROL_OFFSET, stReg.ulTemp);

    /*set counts  = 0*/
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SICOUNTER_OFFSET, 0);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SI2COUNTER_OFFSET, 0);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SCCOUNTER_OFFSET, 0);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_DIVCOUNTER_OFFSET, 0);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_DLYCOUNTER_OFFSET, 0);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_MCOUNTER_OFFSET, 0);

    /** clear AD configuration*/
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_CHANNELCONFIG_OFFSET, 0);

    /** Disable all AD hardware interrupt */
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTCONTROL_OFFSET, 0);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADFIFOCONTROL_OFFSET, 0x0f);

    return OK;
}

/*read one channel's analog input once, notice: when use this function
 *the depth of the channel gain queue must be configed to 1 */
int cPCI9116_Single_AD_Read(unsigned char uchBoardNo, float *pfInput)
{
    CPCI9116_REG_UNION stReg;
    int i = 0;
    unsigned long ulData = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_Single_AD_Read:the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_Single_AD_Read:Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    stReg.ulTemp = 0;

    /** Start Soft_Trig */
    stReg.stAdTrig.SoftConv = 1;

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADTRIGGERMODE_OFFSET, stReg.ulTemp);

    /* * Polling AD status for AD Ready */
    for (i = 0; i < 200; i++)
    {
        stReg.ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADFIFOSTATUS_OFFSET);

        if (!stReg.stAdStatus.FifoEmpty)
        {

            ulData = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADDATA_OFFSET) & 0xffff;

            *pfInput = (double) ulData * cPCI9116_stAdRange[uchBoardNo][0].dResolution
                       + cPCI9116_stAdRange[uchBoardNo][0].dValue;

            return OK;
        }
    }

    printf("cPCI9116_Single_AD_Read: Conversion Timeout!! \n");

    return ERROR;
}
/*interrupt handle proc*/
int cPCI9116_Int_Handle(unsigned char uchBoardNo)
{
    CPCI9116_REG_UNION stReg;
    OP_REG_ST stOpReg;
    unsigned long ulTemp = 0;
    int i = 0;

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTGENERATION_OFFSET, 0);

    stOpReg.ulTemp = 0;
    stOpReg.ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + AMCC5935_INTCONTROL_OFFSET);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + AMCC5935_INTCONTROL_OFFSET, stOpReg.ulTemp | 0x00bf0000);

    Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x18);

    ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTREASON_OFFSET);

    if ((ulTemp & 0x08) != 0)
    {

        /*read out the data fifo*/
        if (cPCI9116_szFlag[uchBoardNo] == 0)
        {
            for (i = 0; i < cPCI9116_uchCGQCount[uchBoardNo] * cPCI9116_ulScanCount[uchBoardNo]; i++)
            {
                ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADDATA_OFFSET) & 0xffff;
                cPCI9116_pulData[uchBoardNo][0][i] = (unsigned short) ulTemp;

            }

            cPCI9116_szFlag[uchBoardNo] = 1;
        }
        else
        {
            for (i = 0; i < cPCI9116_uchCGQCount[uchBoardNo] * cPCI9116_ulScanCount[uchBoardNo]; i++)
            {
                ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADDATA_OFFSET) & 0xffff;
                cPCI9116_pulData[uchBoardNo][1][i] = (unsigned short) ulTemp;

            }

            cPCI9116_szFlag[uchBoardNo] = 0;
        }

    }

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SCCOUNTER_OFFSET, cPCI9116_ulScanCount[uchBoardNo]);

    stReg.ulTemp = 0;
    stReg.stIntCtrl.ClearScanCounterTCInt = 1;
    stReg.stIntCtrl.ScanCounterTC = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTCONTROL_OFFSET, stReg.ulTemp);

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTGENERATION_OFFSET, 1);
    return OK;
}

/*data acquisition config in interrupt mode*/
int cPCI9116_Int_Config(unsigned char uchBoardNo, unsigned long ulScanInterval, unsigned long ulSampleInterval, unsigned long ulScanCount)
{
    CPCI9116_REG_UNION stReg;
    OP_REG_ST stOpReg;
    unsigned long ulSI = 0;
    unsigned long ulSI2 = 0;
    stReg.ulTemp = 0;
    stOpReg.ulTemp = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_Int_Config: the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_Int_Config: Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    /*2^24 / 24M * 1000000 = 699050*/
    if (ulScanInterval > 699000)
    {
        printf("cPCI9116_Int_Config: ulScanInterval must be less than 699000 \n");
        return ERROR;
    }

    /* 2^16 / 24M * 1000000 = 2730*/
    if ((ulSampleInterval < 4) || (ulSampleInterval > 2730))
    {
        printf("cPCI9116_Int_Config: config error, ulSampleInterval must be between 4 and 2730 \n");
        return ERROR;
    }

    if (ulScanInterval < ulSampleInterval * cPCI9116_uchCGQCount[uchBoardNo])
    {
        printf(
            "cPCI9116_Int_Config: config error, ulScanInterval must not be less than ulSampleInterval * cPCI9116_uchCGQCount[uchBoardNo] \n");
        return ERROR;
    }

    if (cPCI9116_uchCGQCount[uchBoardNo] * ulScanCount > 1024)
    {
        printf("cPCI9116_Int_Config: cPCI9116_uchCGQCount[uchBoardNo] * ulScanCount must be no more than 1024 \n");
        return ERROR;
    }

#if(CPU==PPC85XX)

    intDisable(cPCI9116_stInfo[uchBoardNo].uchIrqNo);

    if(intConnect(INUM_TO_IVEC((cPCI9116_stInfo[uchBoardNo].uchIrqNo)), (VOIDFUNCPTR)cPCI9116_Int_Handle, uchBoardNo) == ERROR)
    {
        printf("cPCI9116_Int_Config: intConnect error\n");
        return ERROR;
    }

    intEnable(cPCI9116_stInfo[uchBoardNo].uchIrqNo);

#else

#if VX_9116_IO_MODE == VX_9116_IO_INT
    sysIntDisablePIC(cPCI9116_stInfo[uchBoardNo].uchIrqNo);

    if (pciIntConnect(INUM_TO_IVEC(INT_NUM_GET(cPCI9116_stInfo[uchBoardNo].uchIrqNo)),
                      (VOIDFUNCPTR) cPCI9116_Int_Handle, uchBoardNo) == ERROR)
    {
        printf("cPCI9116_Int_Config: intConnect error\n");
        return ERROR;
    }

    sysIntEnablePIC(cPCI9116_stInfo[uchBoardNo].uchIrqNo);
#endif
    
#endif

    /*set the number of the samples per scan*/
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_DIVCOUNTER_OFFSET, cPCI9116_uchCGQCount[uchBoardNo]);

    /*set the sample interval*/
    ulSI2 = ulSampleInterval * 24;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SI2COUNTER_OFFSET, ulSI2);

    /*set the scan interval*/
    ulSI = ulScanInterval * 24;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SICOUNTER_OFFSET, ulSI);

    cPCI9116_ulScanCount[uchBoardNo] = ulScanCount;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SCCOUNTER_OFFSET, ulScanCount);

    stReg.ulTemp = 0;
    stReg.stIntCtrl.ScanCounterTC = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTCONTROL_OFFSET, stReg.ulTemp);

    stOpReg.ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + AMCC5935_INTCONTROL_OFFSET);
    stOpReg.stIntcsr.C_IMB_IE = 1;
    stOpReg.stIntcsr.C_IMB_MBX = 3;
    stOpReg.stIntcsr.C_IMB_BYTE = 3;
    stOpReg.stIntcsr.S_A2P_FIFO_ADVANCE_BYTE = 2;
    stOpReg.stIntcsr.S_P2A_FIFO_ADVANCE_BYTE = 2;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + AMCC5935_INTCONTROL_OFFSET, stOpReg.ulTemp);

    return OK;
}

/*start data acquisition*/
int cPCI9116_Start_AD(unsigned char uchBoardNo)
{
    CPCI9116_REG_UNION stReg;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_Start_AD: the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_Start_AD: Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SCCOUNTER_OFFSET, cPCI9116_ulScanCount[uchBoardNo]);

    /*enable acquisition*/
    stReg.ulTemp = 0;
    stReg.stAdTrig.EnableACQ = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADTRIGGERMODE_OFFSET, stReg.ulTemp);
    return OK;
}

/*stop data acquisition*/
int cPCI9116_Stop_AD(unsigned char uchBoardNo)
{
    CPCI9116_REG_UNION stReg;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_Stop_AD: the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_Stop_AD: Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    /*disable acquistion*/
    stReg.ulTemp = 0;
    stReg.stAdTrig.EnableACQ = 0;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADTRIGGERMODE_OFFSET, stReg.ulTemp);

    return OK;
}

/*get the the data region pointer*/
int cPCI9116_GetData(unsigned char uchBoardNo, float **pdData)
{
    int i = 0;
    short shtemp = 0;

    if (uchBoardNo >= CPCI9116_BOARD_MAX)
    {
        printf("cPCI9116_GetData: the uchBoardNo should be less than %d \n", CPCI9116_BOARD_MAX);
        return ERROR;
    }

    if (cPCI9116_stInfo[uchBoardNo].uchInit == 0)
    {
        printf("cPCI9116_GetData: Board[%d] is not initialized \n", uchBoardNo);
        return ERROR;
    }

    if (cPCI9116_szFlag[uchBoardNo] == 0)
    {
        for (i = 0; i < cPCI9116_uchCGQCount[uchBoardNo] * cPCI9116_ulScanCount[uchBoardNo]; i++)
        {
            shtemp = (short) cPCI9116_pulData[uchBoardNo][1][i];
            cPCI9116_pdData[uchBoardNo][1][i] = (float) shtemp * cPCI9116_stAdRange[uchBoardNo][i
                                                % (cPCI9116_uchCGQCount[uchBoardNo])].dResolution + cPCI9116_stAdRange[uchBoardNo][i
                                                        % (cPCI9116_uchCGQCount[uchBoardNo])].dValue;
        }

        *pdData = &cPCI9116_pdData[uchBoardNo][1][0];
    }
    else
    {
        for (i = 0; i < cPCI9116_uchCGQCount[uchBoardNo] * cPCI9116_ulScanCount[uchBoardNo]; i++)
        {
            shtemp = (short) cPCI9116_pulData[uchBoardNo][0][i];
            cPCI9116_pdData[uchBoardNo][0][i] = (float) shtemp * cPCI9116_stAdRange[uchBoardNo][i
                                                % (cPCI9116_uchCGQCount[uchBoardNo])].dResolution + cPCI9116_stAdRange[uchBoardNo][i
                                                        % (cPCI9116_uchCGQCount[uchBoardNo])].dValue;
        }

        *pdData = &cPCI9116_pdData[uchBoardNo][0][0];
    }

    return OK;
}

/*get the specified channel's data
 *note: when use this function ,the channel
 *gain queue must not have the same channel*/
int cPCI9116_GetData_Chan(unsigned char uchBoardNo, unsigned char uchChannel, float **pdData)
{
    int i = 0;
    int j = 0;
    /*short shtemp = 0;*/
    float *pfTemp = NULL;

    if (uchChannel > 63)
    {
        printf("cPCI9116_GetData_Chan: the channel should be between 0 and 63 \n");
        return ERROR;
    }

    if (cPCI9116_GetData(uchBoardNo, &pfTemp) == ERROR)
    {
        return ERROR;
    }
    else
    {
        for (i = 0; i < cPCI9116_uchCGQCount[uchBoardNo]; i++)
        {
            if (cPCI9116_stAdRange[uchBoardNo][i].uchChanNo == uchChannel)
            {
                for (j = 0; j < cPCI9116_ulScanCount[uchBoardNo]; j++)
                {
                    cPCI9116_pdData_Chan[uchBoardNo][uchChannel][j] = pfTemp[i + j * cPCI9116_uchCGQCount[uchBoardNo]];
                }
                break;
            }
        }
    }

    return OK;
}

/*test function*/
int cPCI9116_Is_Init(unsigned char uchBoardNo)
{
    return cPCI9116_stInfo[uchBoardNo].uchInit == 1;
}

#if VX_9116_IO_MODE == VX_9116_IO_FETCH
int cPCI9116_FetchData(unsigned char uchBoardNo)
{
    CPCI9116_REG_UNION stReg;
    OP_REG_ST stOpReg;
    unsigned long ulTemp = 0;
    int i = 0;

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTGENERATION_OFFSET, 0);

    stOpReg.ulTemp = 0;
    stOpReg.ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + AMCC5935_INTCONTROL_OFFSET);
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + AMCC5935_INTCONTROL_OFFSET, stOpReg.ulTemp | 0x00bf0000);

    Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulCtrlAddr + 0x18);

    ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTREASON_OFFSET);

    if ((ulTemp & 0x08) != 0)
    {

        /*read out the data fifo*/
        if (cPCI9116_szFlag[uchBoardNo] == 0)
        {
            for (i = 0; i < cPCI9116_uchCGQCount[uchBoardNo] * cPCI9116_ulScanCount[uchBoardNo]; i++)
            {
                ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADDATA_OFFSET) & 0xffff;
                cPCI9116_pulData[uchBoardNo][0][i] = (unsigned short) ulTemp;

            }

            cPCI9116_szFlag[uchBoardNo] = 1;
        }
        else
        {
            for (i = 0; i < cPCI9116_uchCGQCount[uchBoardNo] * cPCI9116_ulScanCount[uchBoardNo]; i++)
            {
                ulTemp = Local_sysInLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_ADDATA_OFFSET) & 0xffff;
                cPCI9116_pulData[uchBoardNo][1][i] = (unsigned short) ulTemp;

            }

            cPCI9116_szFlag[uchBoardNo] = 0;
        }

    }

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_SCCOUNTER_OFFSET, cPCI9116_ulScanCount[uchBoardNo]);

    stReg.ulTemp = 0;
    stReg.stIntCtrl.ClearScanCounterTCInt = 1;
    stReg.stIntCtrl.ScanCounterTC = 1;
    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTCONTROL_OFFSET, stReg.ulTemp);

    Local_sysOutLong(cPCI9116_stInfo[uchBoardNo].ulBaseAddr + CPCI9116_INTGENERATION_OFFSET, 1);
    return OK;
}
#endif
